package org.fund.common.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.fund.common.constant.ErrorCode;
import org.fund.common.constant.FundEnum;
import org.fund.common.exception.ServiceException;
import org.fund.common.model.Fund;
import org.fund.common.model.FundEstimate;
import org.fund.common.model.FundValue;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Author Moro
 * @Date 2022/3/7 22:07
 * @title FundUtils
 */
public class FundUtils {
    //
    public static final String allFundUrl = "https://fundapi.eastmoney.com/fundtradenew.aspx?ft=%s&sc=1n&st=desc&pi=1&pn=65536&cp=&ct=&cd=&ms=&fr=&plevel=&fst=&ftype=&fr1=&fl=0&isab=1";
    // 查找所有基金的地址
    public static final String allFundUrl1 = "http://fund.eastmoney.com/data/rankhandler.aspx?op=ph&dt=kf&ft=%s&rs=&gs=0&sc=6yzf&st=desc&sd=%s&ed=%s&qdii=&tabSubtype=,,,,,&pi=1&pn=1000&dx=1&v=%s";
    // 代理
    public static String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36";
    // 查找所有基金的referer
    public static final String allDataReferer = "http://fund.eastmoney.com/data/fundranking.html";

    // 查找某只基金的referer
    public static final String searchFundReferer = "http://fundf10.eastmoney.com";

    // 查找某只基金当日估值的referer
    public static final String estimateReferer="http://fund.eastmoney.com";
    // 查找某只基金当日估值的地址
    public static final String estimateUrl = "http://fundgz.1234567.com.cn/js/%s.js?rt=%s";
    public static final   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 爬取处理所有基金
     * @param fundType
     * @return
     */
    public static List<List<String>> getFundDataWithFundType(FundEnum fundType) {
        Date date = new Date();
        String now = sdf.format(date);
        String code = FundEnum.getCode(fundType);
        HttpRequest httpRequest = HttpRequest.get(String.format(allFundUrl1,code,now,now,"0."+System.currentTimeMillis()));
        httpRequest.header("User-Agent", userAgent);
        httpRequest.header("Referer", allDataReferer);
        String body = httpRequest.execute().body();
        String replace = body.replace("var rankData = {datas:[", "");

        int i1 = replace.indexOf("]");
        String substring = replace.substring(0,i1-1);
        String[] split = substring.split("\",\"");
        List<List<String>> fundData = new ArrayList<>();
        for (String s : split) {
            String[] e = s.split(",");
            List<String> temp = new ArrayList<>(e.length);
            temp.addAll(Arrays.asList(e));
            fundData.add(temp);
        }
        return fundData;
    }

    /**
     * 根据爬取的基金数据 组装成所有基金集合
     * @param fundEnum
     * @return
     */
    public static List<Fund> getFunds(FundEnum fundEnum) {
        List<List<String>> list = getFundDataWithFundType(fundEnum);
        List<Fund> funds = new ArrayList<>(list.size());
        for (List<String> tempList : list) {
            Fund fund = new Fund();
            fund.setCode(tempList.get(0));
            fund.setName(tempList.get(1));
            fund.setDate(tempList.get(3));
            fund.setNetValue(strToDouble(tempList.get(4)));
            fund.setSumValue(strToDouble(tempList.get(5)));
            fund.setDayRise(strToDouble(tempList.get(6)));
            fund.setWeekRise(strToDouble(tempList.get(7)));
            fund.setMonthRise(strToDouble(tempList.get(8)));
            fund.setThreeMonthsRise(strToDouble(tempList.get(9)));
            fund.setSixMonthsRise(strToDouble(tempList.get(10)));
            fund.setOneYearRise(strToDouble(tempList.get(11)));
            fund.setTwoYearsRise(strToDouble(tempList.get(12)));
            fund.setThreeYearsRise(strToDouble(tempList.get(13)));
            fund.setCurYearRise(strToDouble(tempList.get(14)));
            fund.setHistoryRise(strToDouble(tempList.get(15)));
            if (tempList.size()>20){
                fund.setPoundage(strToBig(tempList.get(20)));
            }
            funds.add(fund);
        }
        return funds;
    }

    public static Double strToDouble(String str) {
        str = str.replace(",", "");
        return StringUtils.isEmpty(str) ? 0 : Double.valueOf(str);
    }

    public static BigDecimal strToBig(String str) {
        str = str.replace("%", "");
        return StringUtils.isEmpty(str) ? new BigDecimal(0) : new BigDecimal(str);
    }

    /**
     *  根据基金代码获得历史净值
     * @param code 基金代码
     * @param pageSize 条数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    public static List<FundValue> lsjz(String code, Integer pageSize, String startTime,String endTime){
        long time = System.currentTimeMillis();

        String url = "http://api.fund.eastmoney.com/f10/lsjz?" +"callback=jQuery18309071382116865634_1646556119321"+
                "&fundCode=%s&pageIndex=1&pageSize=%s&startDate=%s&endDate=%s&_=%s";
        url = String.format(url, code,  pageSize, startTime, endTime, time);
        String str = getResponseBody(url);
        int indexStart = str.indexOf("(");
        int indexLast = str.indexOf("]");
        //计算json字符
        str = str.substring(indexStart+9,indexLast+1);
        JSONObject jsonObject = JSON.parseObject(str+"}");
        JSONArray jsonArray = jsonObject.getJSONArray("LSJZList");
        List<FundValue> fundValues = JSONObject.parseArray(jsonArray.toJSONString(), FundValue.class);
        return  fundValues;

    }

    /**
     * 根据基金编号获取当日净值
     * @param code
     * @return
     */
    public  static FundEstimate getJZEstimate(String code){
        HttpRequest httpRequest = HttpRequest.get(String.format(estimateUrl,code,System.currentTimeMillis()));
        httpRequest.header("User-Agent",userAgent);
        httpRequest.header("Referer", estimateReferer);
        String body = httpRequest.execute().body();
        String replace = body.replace("jsonpgz(", "");
        replace = replace.substring(0, replace.length()-2);
        return JSON.parseObject(replace, FundEstimate.class);
    }

    private static String getResponseBody(String url) {
        HttpRequest request = HttpUtil.createGet(url);
        request.header("Referer", searchFundReferer);
        request.header("User-Agent",userAgent);
        return request.execute().body();
    }

}
